package es.aqua.aquac.il.domain;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import es.aqua.aquac.exception.GeneralBusinessException;
import es.aqua.aquac.util.Constants;
import es.aqua.aquac.util.Utiles;

@MappedSuperclass
public class BaseDomainObject extends GeneralDomainObject implements Serializable {

	/**
	 * Atributo serialVersionUID.
	 */
	private static final long serialVersionUID = 6570818726931423004L;

	/**
	 * Auditoría.
	 */

	@Column(name = "BORRADO_LOGICO")
	private Boolean borradoLogico;

	/**
	 * Auditoría.
	 */
	@Column(name = "PUESTO_ALTA", length = Constants.DB_TAM_TEXTO_PEQUENO)
	private String puestoAlta;

	/**
	 * Auditoría.
	 */
	@Column(name = "PUESTO_MODIFICACION", length = Constants.DB_TAM_TEXTO_PEQUENO)
	private String puestoModificacion;

	/**
	 * Auditoría.
	 */
	@Column(name = "ROL_ALTA", length = Constants.DB_TAM_TEXTO_PEQUENO)
	private String rolAlta;

	/**
	 * Auditoría.
	 */
	@Column(name = "ROL_MODIFICACION", length = Constants.DB_TAM_TEXTO_PEQUENO)
	private String rolModificacion;

	/**
	 * Usuario de la solicitud.
	 */
	@Column(name = "USUARIO_ALTA", length = Constants.DB_TAM_TEXTO_PEQUENO)
	private String usuarioAlta;

	/**
	 * Usuario que modifica la solicitud.
	 */
	@Column(name = "USUARIO_MODIFICACION", length = Constants.DB_TAM_TEXTO_PEQUENO)
	private String usuarioModificacion;

	/**
	 * Fecha de alta de la solicitud.
	 */
	@Column(name = "FECHA_ALTA")
	@Temporal(TemporalType.TIMESTAMP)
	private Date fechaAlta;

	/**
	 * Fecha modificacion de la solicitud.
	 */
	@Column(name = "FECHA_MODIFICACION")
	@Temporal(TemporalType.TIMESTAMP)
	private Date fechaModificacion;

	/**
	 * @return the puestoAlta
	 */
	public String getPuestoAlta() {
		return puestoAlta;
	}

	/**
	 * @param puestoAlta
	 *            the puestoAlta to set
	 */
	public void setPuestoAlta(String puestoAlta) {
		this.puestoAlta = puestoAlta;
	}

	/**
	 * @return the puestoModificacion
	 */
	public String getPuestoModificacion() {
		return puestoModificacion;
	}

	/**
	 * @param puestoModificacion
	 *            the puestoModificacion to set
	 */
	public void setPuestoModificacion(String puestoModificacion) {
		this.puestoModificacion = puestoModificacion;
	}

	/**
	 * @return the rolAlta
	 */
	public String getRolAlta() {
		return rolAlta;
	}

	/**
	 * @param rolAlta
	 *            the rolAlta to set
	 */
	public void setRolAlta(String rolAlta) {
		this.rolAlta = rolAlta;
	}

	/**
	 * @return the rolModificacion
	 */
	public String getRolModificacion() {
		return rolModificacion;
	}

	/**
	 * @param rolModificacion
	 *            the rolModificacion to set
	 */
	public void setRolModificacion(String rolModificacion) {
		this.rolModificacion = rolModificacion;
	}

	/**
	 * @return the usuarioAlta
	 */
	public String getUsuarioAlta() {
		return usuarioAlta;
	}

	/**
	 * @param usuarioAlta
	 *            the usuarioAlta to set
	 */
	public void setUsuarioAlta(String usuarioAlta) {
		this.usuarioAlta = usuarioAlta;
	}

	/**
	 * @return the usuarioModificacion
	 */
	public String getUsuarioModificacion() {
		return usuarioModificacion;
	}

	/**
	 * @param usuarioModificacion
	 *            the usuarioModificacion to set
	 */
	public void setUsuarioModificacion(String usuarioModificacion) {
		this.usuarioModificacion = usuarioModificacion;
	}

	/**
	 * @return the fechaAlta
	 */
	public Date getFechaAlta() {
		return fechaAlta;
	}

	/**
	 * @param fechaAlta
	 *            the fechaAlta to set
	 */
	public void setFechaAlta(Date fechaAlta) {
		this.fechaAlta = fechaAlta;
	}

	/**
	 * @return the fechaModificacion
	 */
	public Date getFechaModificacion() {
		return fechaModificacion;
	}

	/**
	 * @param fechaModificacion
	 *            the fechaModificacion to set
	 */
	public void setFechaModificacion(Date fechaModificacion) {
		this.fechaModificacion = fechaModificacion;
	}

	public Boolean getBorradoLogico() {
		return borradoLogico;
	}

	public void setBorradoLogico(Boolean borradoLogico) {
		this.borradoLogico = borradoLogico;
	}

	@PreUpdate
	@PrePersist
	public void cambiarVaciosNulosEnManyToOne() throws GeneralBusinessException {
		try {
			Field[] atributos = this.getClass().getDeclaredFields();
			for (int i = 0; i < atributos.length; i++) {
				Field atributo = atributos[i];
				if (atributo.getType().getName().contains("com.unav.actividades.il.domain")) {
					Method metodo = this.getClass().getMethod("get" + Utiles.textoMayuscula(atributo.getName()), new Class[] {});
					Object o = metodo.invoke(this, new Object[] {});
					if (o != null) {
						metodo = o.getClass().getMethod("getId", new Class[] {});
						Integer id = (Integer) metodo.invoke(o, new Object[] {});
						if (id == null || id < 0) {
							metodo = this.getClass().getMethod("set" + Utiles.textoMayuscula(atributo.getName()), new Class[] { atributo.getType() });
							metodo.invoke(this, new Object[] { null });
						}
					}
				}
			}
		} catch (IllegalArgumentException e) {
			throw new GeneralBusinessException("Duplicar Objeto", "Error al duplica los datos del objeto");
		} catch (IllegalAccessException e) {
			throw new GeneralBusinessException("Duplicar Objeto", "Error al duplica los datos del objeto");
		} catch (InvocationTargetException e) {
			throw new GeneralBusinessException("Duplicar Objeto", "Error al duplica los datos del objeto");
		} catch (SecurityException e) {
			throw new GeneralBusinessException("Duplicar Objeto", "Error al duplica los datos del objeto");
		} catch (NoSuchMethodException e) {
			throw new GeneralBusinessException("Duplicar Objeto", "Error al duplica los datos del objeto");
		}
	}

}
